/**
 *------------------------------------------------------------------------------
 *  @copyright Copyright (c) 2022  <dx_65535@163.com>. 
 * 
 *  @file       : msg_queue.cc
 *  @author     : Xiang.D (dx_65535@163.com)
 *  @version    : 1.0
 *  @brief      : Blog: https://linuxtaoist.gitee.io
 *  @date       : 2022-04-03
 * 
 * 
 *  Change History:
 *  <Date>     | <Version> | <Author>       | <Description>
 *------------------------------------------------------------------------------
 *  2022/04/03 | 1.0.0.1   | Xiang.D        | Create file
 *------------------------------------------------------------------------------
 * 
 */

#include <stdio.h>
#include "msg_queue.h"
#include <mqueue.h>
#include <errno.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>

#define QLOGE(fmt, args...)  printf("%d MsgQ E: " fmt, __LINE__, ##args)

#ifdef TEST_DEBUG
#define QLOGD(fmt, args...)  printf("%d MsgQ D: " fmt, __LINE__, ##args)
#else
#define QLOGD(fmt, args...) 
#endif

CMsgQueue theMsgQueue("/EventHandlerQ", 10);

CMsgQueue::CMsgQueue(const char *name, long maxMsg)
{
    mQueueName = name;
    mQueueSize = maxMsg;
}

CMsgQueue::~CMsgQueue()
{
    if (mFd > 0) {
        mq_close(mFd);
        QLOGD("msg_queue fd(%d) close\n", mFd);
    }
}

int CMsgQueue::Init()
{
    int ret = 0;
    mq_attr mqAttr;
    mqAttr.mq_maxmsg = 10;      // cat /proc/sys/fs/mqueue/msg_max
    mqAttr.mq_msgsize = 1025;

    mq_unlink(mQueueName.c_str());
    QLOGD("Unlink queue!\n");
    mFd = (int)mq_open(mQueueName.c_str(), O_RDONLY | O_CREAT | O_EXCL | O_NONBLOCK, 0666, &mqAttr);
    if (mFd < 0)
    {
        QLOGE("open queue %s error[%s]\n", mQueueName.c_str(), strerror(errno));
        ret = -1;
    }

    return ret;
}

int CMsgQueue::Send(const char *msg, int len)
{
    int ret = -1;
    static bool initFlag = false;

    if (!initFlag) {
        mFd = (int)mq_open(mQueueName.c_str(), O_WRONLY);
        if (mFd < 0) {
            QLOGE("%s mq_open failed. (%s)!\n", mQueueName.c_str(), strerror(errno));
            return -1;
        }
        initFlag = true;
    }

    ret = mq_send(mFd, msg, len, 1);
    if (ret == -1) {
        QLOGE("mq_send failed! (%s)\n", strerror(errno));
    } else if (ret == 0) {
        QLOGD("mq_send success.\n");
    } else {
        QLOGD("mq_send invail return.\n");
    }

    return ret;
}

int CMsgQueue::Receive(char *msg, int len)
{
    int ret = -1;
    char tmp[100] = {0};
    unsigned int prio;
    mq_attr mqAttr;

    mq_getattr(mFd, &mqAttr);
    if (mFd < 0) {
        QLOGE("mFd failed. (%d)\n", mFd);
        return -1;    
    }

    ret = mq_receive(mFd, tmp, mqAttr.mq_msgsize, &prio);
    if (ret < 0) {
        //QLOGE("mq_receive failed! (%s)\n", strerror(errno));
        return -1;
    } 

    memcpy(msg, tmp, len);

    return 0;
}
